﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Reflection;
using System.IO;
using System.Globalization;
using System.Net.Sockets;
using System.Net;

namespace Microsoft.Office.Project.EPMAuditing.Library
{
    public class Tracing : IDisposable
    {
        private const int _maxLogFileSize = 1024000;

        private System.IO.FileStream _traceLog;
        private System.Diagnostics.TextWriterTraceListener _fileTraceListener;
        private System.Diagnostics.TraceSwitch _TraceSwitch;
        private string _currentFileName = string.Empty;
        private string _coreFileName = "EPMAuditing-Trace";
        
        public Tracing() { }

        public Tracing(string coreFileName, TraceLevel tracingLevel)
        {
            _coreFileName = coreFileName;
            SetTraceLevel(tracingLevel);
        }

        public Tracing(TraceLevel tracingLevel)
        {
            SetTraceLevel(tracingLevel);
        }


        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                Trace.Listeners.Remove(_fileTraceListener);
                _fileTraceListener.Close();
                _fileTraceListener.Dispose();
                _traceLog.Close();

            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(true);
        }

        private void SetTraceLevel(TraceLevel tracingLevel)
        {
            AddFileTraceListener();

            Trace.AutoFlush = true;
            _TraceSwitch = new System.Diagnostics.TraceSwitch("MainSwitch", "The main switch");
            _TraceSwitch.Level = tracingLevel;
        }

        private static string DefaultFileDirectory
        {
            get
            {
                string fullPath = Assembly.GetExecutingAssembly().Location;
                string directory = fullPath.Substring(0, fullPath.LastIndexOf(@"\", StringComparison.OrdinalIgnoreCase) + 1);
                return String.Format(CultureInfo.InvariantCulture, @"{0}Trace\", directory);
            }
        }

        private void AddFileTraceListener()
        {
            _currentFileName = String.Format(CultureInfo.InvariantCulture, @"{0}{1} {2}.txt", DefaultFileDirectory, _coreFileName, 
                DateTime.Now.ToString("yyyyMMdd-HHmmss", DateTimeFormatInfo.InvariantInfo));

            _traceLog = new System.IO.FileStream(_currentFileName, System.IO.FileMode.OpenOrCreate);
            _fileTraceListener = new System.Diagnostics.TextWriterTraceListener(_traceLog);
            Trace.Listeners.Add(_fileTraceListener);
        }


        private void StartNewFileIfPastSize(long fileSize)
        {
            FileInfo fi = new FileInfo(_currentFileName);
            if (fi.Length > fileSize)
            {
                Trace.Listeners.Remove(_fileTraceListener);
                _fileTraceListener.Close();
                _traceLog.Close();
                AddFileTraceListener();
            }
        }

        public TraceSwitch MainSwitch
        {
            get
            {
                return _TraceSwitch;
            }
        }

        public void WriteTrace(bool traceLevel, string output)
        {
            StackTrace stackTrace = new StackTrace();
            StackFrame stackFrame = stackTrace.GetFrame(1);
            MethodBase methodBase = stackFrame.GetMethod();

            Trace.WriteLineIf(traceLevel, String.Format(CultureInfo.InvariantCulture, "{0}.{1}, {2}, {3}",
                methodBase.ReflectedType, methodBase.Name, DateTime.Now.ToString("s", DateTimeFormatInfo.InvariantInfo), output));

            StartNewFileIfPastSize(_maxLogFileSize);
        }


    }

}
